home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / read.c < prev    next >
C/C++ Source or Header  |  1993-01-04  |  31KB  |  1,177 lines

  1. /*    SCCS Id: @(#)read.c    3.1    92/12/10    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. /* elven armor vibrates warningly when enchanted beyond a limit */
  8. #define is_elven_armor(optr)    ((optr)->otyp == ELVEN_LEATHER_HELM\
  9.                 || (optr)->otyp == ELVEN_MITHRIL_COAT\
  10.                 || (optr)->otyp == ELVEN_CLOAK\
  11.                 || (optr)->otyp == ELVEN_SHIELD\
  12.                 || (optr)->otyp == ELVEN_BOOTS)
  13.  
  14. #ifdef OVLB
  15.  
  16. boolean    known;
  17.  
  18. static const char NEARDATA readable[] =
  19.            { ALL_CLASSES, SCROLL_CLASS, SPBOOK_CLASS, 0 };
  20. static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 };
  21.  
  22. static void FDECL(wand_explode, (struct obj *));
  23. static void NDECL(do_class_genocide);
  24. static void FDECL(stripspe,(struct obj *));
  25. static void FDECL(p_glow1,(struct obj *));
  26. static void FDECL(p_glow2,(struct obj *,const char *));
  27. static void FDECL(forget,(BOOLEAN_P));
  28.  
  29. #endif /* OVLB */
  30.  
  31. #ifndef OVERLAY
  32. STATIC_DCL void FDECL(set_lit, (int,int,genericptr_t));
  33. #endif
  34.  
  35. #ifdef OVLB
  36.  
  37. int
  38. doread()
  39. {
  40.     register struct obj *scroll;
  41.     register boolean confused;
  42.  
  43.     known = FALSE;
  44.     if(check_capacity(NULL)) return (0);
  45.     scroll = getobj(readable, "read");
  46.     if(!scroll) return(0);
  47.  
  48.     /* outrumor has its own blindness check */
  49.     if(scroll->otyp == FORTUNE_COOKIE) {
  50.         if(flags.verbose)
  51.         You("break up the cookie and throw away the pieces.");
  52.         outrumor(bcsign(scroll), TRUE);
  53.         useup(scroll);
  54.         return(1);
  55.     } else if (scroll->oclass != SCROLL_CLASS
  56.         && scroll->oclass != SPBOOK_CLASS) {
  57.         pline(silly_thing_to, "read");
  58.         return(0);
  59.     } else if (Blind) {
  60.         const char *what = 0;
  61.         if (scroll->oclass == SPBOOK_CLASS)
  62.         what = "mystic runes";
  63.         else if (!scroll->dknown)
  64.         what = "formula on the scroll";
  65.         if (what) {
  66.         pline("Being blind, you cannot read the %s.", what);
  67.         return(0);
  68.         }
  69.     }
  70.  
  71.     confused = (Confusion != 0);
  72.     if(scroll->oclass == SPBOOK_CLASS) {
  73.         if(confused) {
  74.         You("cannot grasp the meaning of this tome.");
  75.         return(0);
  76.         } else
  77.         return(study_book(scroll));
  78.     }
  79. #ifndef NO_SIGNAL
  80.     scroll->in_use = TRUE;    /* scroll, not spellbook, now being read */
  81. #endif
  82.     if(scroll->otyp != SCR_BLANK_PAPER) {
  83.       if(Blind)
  84.         pline("As you pronounce the formula on it, the scroll disappears.");
  85.       else
  86.         pline("As you read the scroll, it disappears.");
  87.       if(confused) {
  88.         if (Hallucination)
  89.         pline("Being so trippy, you screw up....");
  90.         else
  91.         pline("Being confused, you mispronounce the magic words....");
  92.       }
  93.     }
  94.     if(!seffects(scroll))  {
  95.         if(!objects[scroll->otyp].oc_name_known) {
  96.             if(known) {
  97.             makeknown(scroll->otyp);
  98.             more_experienced(0,10);
  99.             } else if(!objects[scroll->otyp].oc_uname)
  100.             docall(scroll);
  101.         }
  102.         if(scroll->otyp != SCR_BLANK_PAPER)
  103.             useup(scroll);
  104. #ifndef NO_SIGNAL
  105.         else scroll->in_use = FALSE;
  106. #endif
  107.     }
  108.     return(1);
  109. }
  110.  
  111. static void
  112. stripspe(obj)
  113. register struct obj *obj;
  114. {
  115.     if (obj->blessed) pline(nothing_happens);
  116.     else {
  117.         if (obj->spe > 0) {
  118.             obj->spe = 0;
  119.             if (obj->otyp == OIL_LAMP || obj->otyp == BRASS_LANTERN)
  120.             obj->age = 0;
  121.             Your("%s vibrates briefly.",xname(obj));
  122.         } else pline(nothing_happens);
  123.     }
  124. }
  125.  
  126. static void
  127. p_glow1(otmp)
  128. register struct obj    *otmp;
  129. {
  130.     Your("%s %s briefly.", xname(otmp),
  131.         Blind ? "vibrates" : "glows");
  132. }
  133.  
  134. static void
  135. p_glow2(otmp,color)
  136. register struct obj    *otmp;
  137. register const char *color;
  138. {
  139.     Your("%s %s%s for a moment.",
  140.         xname(otmp),
  141.         Blind ? "vibrates" : "glows ",
  142.         Blind ? (const char *)"" : Hallucination ? hcolor() : color);
  143. }
  144.  
  145. /*
  146.  * recharge an object; curse_bless is -1 if the recharging implement
  147.  * was cursed, +1 if blessed, 0 otherwise.
  148.  */
  149. void
  150. recharge(obj, curse_bless)
  151. struct obj *obj;
  152. int curse_bless;
  153. {
  154.     register int n;
  155.     boolean is_cursed, is_blessed;
  156.  
  157.     is_cursed = curse_bless < 0;
  158.     is_blessed = curse_bless > 0;
  159.  
  160.     if (obj->oclass == WAND_CLASS) {
  161.         if (obj->otyp == WAN_WISHING) {
  162.         if (obj->recharged) {    /* recharged once already? */
  163.             wand_explode(obj);
  164.             return;
  165.         }
  166.         if (is_cursed) stripspe(obj);
  167.         else if (is_blessed) {
  168.             if (obj->spe != 3) {
  169.             obj->spe = 3;
  170.             p_glow2(obj,blue);
  171.             } else {
  172.             wand_explode(obj);
  173.             return;
  174.             }
  175.         } else {
  176.             if (obj->spe < 3) {
  177.             obj->spe++;
  178.             p_glow2(obj,blue);
  179.             } else pline(nothing_happens);
  180.         }
  181.         obj->recharged = 1; /* another recharging disallowed */
  182.         } else {
  183.         if (is_cursed) stripspe(obj);
  184.         else if (is_blessed) {
  185.             if (objects[obj->otyp].oc_dir == NODIR) {
  186.             n = rn1(5,11);
  187.             if (obj->spe < n) obj->spe = n;
  188.             else obj->spe++;
  189.             } else {
  190.             n = rn1(5,4);
  191.             if (obj->spe < n) obj->spe = n;
  192.             else obj->spe++;
  193.             }
  194.             p_glow2(obj,blue);
  195.         } else {
  196.             obj->spe++;
  197.             p_glow1(obj);
  198.         }
  199.         }
  200.     } else if (obj->oclass == RING_CLASS &&
  201.                     objects[obj->otyp].oc_charged) {
  202.         /* charging does not affect ring's curse/bless status */
  203.         int s = is_blessed ? rnd(3) : is_cursed ? -rnd(2) : 1;
  204.         boolean is_on = (obj == uleft || obj == uright);
  205.  
  206.         /* destruction depends on current state, not adjustment */
  207.         if (obj->spe > rn2(7) || obj->spe <= -5) {
  208.         Your("%s pulsates momentarily, then explodes!",
  209.              xname(obj));
  210.         if (is_on) Ring_gone(obj);
  211.         s = rnd(3 * abs(obj->spe));    /* amount of damage */
  212.         useup(obj);
  213.         losehp(s, "exploding ring", KILLED_BY_AN);
  214.         } else {
  215.         long mask = is_on ? (obj == uleft ? LEFT_RING :
  216.                      RIGHT_RING) : 0L;
  217.         Your("%s spins %sclockwise for a moment.",
  218.              xname(obj), s < 0 ? "counter" : "");
  219.         /* cause attributes and/or properties to be updated */
  220.         if (is_on) Ring_off(obj);
  221.         obj->spe += s;    /* update the ring while it's off */
  222.         if (is_on) setworn(obj, mask), Ring_on(obj);
  223.         /* oartifact: if a touch-sensitive artifact ring is
  224.            ever created the above will need to be revised  */
  225.         }
  226.     } else {
  227.         switch(obj->otyp) {
  228.         case MAGIC_MARKER:
  229.         if (is_cursed) stripspe(obj);
  230.         else if (obj->recharged) {
  231.             if (obj->spe < 3)
  232.             Your("marker seems permanently dried out.");
  233.             else
  234.             pline(nothing_happens);
  235.         } else if (is_blessed) {
  236.             n = obj->spe;
  237.             if (n < 50) obj->spe = 50;
  238.             if (n >= 50 && n < 75) obj->spe = 75;
  239.             if (n >= 75) obj->spe += 10;
  240.             p_glow2(obj,blue);
  241.             obj->recharged = 1;
  242.         } else {
  243.             if (obj->spe < 50) obj->spe = 50;
  244.             else obj->spe++;
  245.             p_glow2(obj,White);
  246.             obj->recharged = 1;
  247.         }
  248.         break;
  249.         case OIL_LAMP:
  250.         case BRASS_LANTERN:
  251.         if (is_cursed) {
  252.             stripspe(obj);
  253.             if (obj->lamplit) {
  254.             if (!Blind)
  255.                 pline("%s goes out!", The(xname(obj)));
  256.             obj->lamplit = 0;
  257.             check_lamps();
  258.             }
  259.         } else if (is_blessed) {
  260.             obj->spe = 1;
  261.             obj->age = 1500;
  262.             p_glow2(obj,blue);
  263.         } else {
  264.             obj->spe = 1;
  265.             obj->age += 750;
  266.             if (obj->age > 1500) obj->age = 1500;
  267.             p_glow1(obj);
  268.         }
  269.         break;
  270.         case CRYSTAL_BALL:
  271.         if (is_cursed) stripspe(obj);
  272.         else if (is_blessed) {
  273.             obj->spe = 6;
  274.             p_glow2(obj,blue);
  275.         } else {
  276.             if (obj->spe < 5) {
  277.             obj->spe++;
  278.             p_glow1(obj);
  279.             } else pline(nothing_happens);
  280.         }
  281.         break;
  282.         case HORN_OF_PLENTY:
  283.         case BAG_OF_TRICKS:
  284.         if (is_cursed) stripspe(obj);
  285.         else if (is_blessed) {
  286.             if (obj->spe <= 10)
  287.             obj->spe += rn1(10, 6);
  288.             else obj->spe += rn1(5, 6);
  289.             p_glow2(obj,blue);
  290.         } else {
  291.             obj->spe += rnd(5);
  292.             p_glow1(obj);
  293.         }
  294.         break;
  295.         default:
  296.         You("have a feeling of loss.");
  297.         break;
  298.         } /* switch */
  299.     }
  300. }
  301.  
  302. /*
  303.  * forget some things (e.g. after reading a scroll of amnesia). abs(howmuch)
  304.  * controls the level of forgetfulness; 0 == part of the map, 1 == all of
  305.  * of map,  2 == part of map + spells, 3 == all of map + spells.
  306.  */
  307.  
  308. static void
  309. forget(howmuch)
  310. boolean howmuch;
  311. {
  312.     register int zx, zy;
  313.     register struct trap *trap;
  314.  
  315.     if (Punished) u.bc_felt = 0;    /* forget felt ball&chain */
  316.  
  317.     known = TRUE;
  318.     for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
  319.         if (howmuch & 1 || rn2(7)) {
  320.         /* Zonk all memory of this location. */
  321.         levl[zx][zy].seen = levl[zx][zy].waslit = 0;
  322.         levl[zx][zy].glyph = cmap_to_glyph(S_stone);
  323.         }
  324.  
  325.     /* forget all traps (except the one the hero is in :-) */
  326.     for (trap = ftrap; trap; trap = trap->ntrap)
  327.         if (trap->tx != u.ux || trap->ty != u.uy) trap->tseen = 0;
  328.  
  329.     /*
  330.      * Make sure that what was seen is restored correctly.  To do this,
  331.      * we need to go blind for an instant --- turn off the display,
  332.      * then restart it.  All this work is needed to correctly handle
  333.      * walls which are stone on one side and wall on the other.  Turning
  334.      * off the seen bit above will make the wall revert to stone,  but
  335.      * there are cases where we don't want this to happen.  The easiest
  336.      * thing to do is to run it through the vision system again, which
  337.      * is always correct.
  338.      */
  339.     docrt();        /* this correctly will reset vision */
  340.  
  341.     if(howmuch & 2) losespells();
  342. }
  343.  
  344. int
  345. seffects(sobj)
  346. register struct obj    *sobj;
  347. {
  348.     register int cval;
  349.     register boolean confused = (Confusion != 0);
  350.     register struct obj *otmp;
  351.  
  352.     exercise(A_WIS, TRUE);        /* just for trying */
  353.     switch(sobj->otyp) {
  354. #ifdef MAIL
  355.     case SCR_MAIL:
  356.         known = TRUE;
  357.         if (sobj->spe)
  358.             pline("This seems to be junk mail addressed to the finder of the Eye of Larn.");
  359.         /* note to the puzzled: the game Larn actually sends you junk
  360.          * mail if you win!
  361.          */
  362.         else readmail(sobj);
  363.         break;
  364. #endif
  365.     case SCR_ENCHANT_ARMOR:
  366.         {
  367.         register schar s;
  368.         otmp = some_armor();
  369.         if(!otmp) {
  370.             strange_feeling(sobj,
  371.                     !Blind ? "Your skin glows then fades." :
  372.                     "Your skin feels warm for a moment.");
  373.             exercise(A_CON, !sobj->cursed);
  374.             exercise(A_STR, !sobj->cursed);
  375.             return(1);
  376.         }
  377.         if(confused) {
  378.             otmp->oerodeproof = !(sobj->cursed);
  379.             if(Blind) {
  380.                 otmp->rknown = FALSE;
  381.                 Your("%s feels warm for a moment.",
  382.                 xname(otmp));
  383.             } else {
  384.                 otmp->rknown = TRUE;
  385.                 Your("%s is covered by a %s %s %s!",
  386.                 xname(otmp),
  387.                 sobj->cursed ? "mottled" : "shimmering",
  388.                 Hallucination ? hcolor() :
  389.                   sobj->cursed ? Black : golden,
  390.                 sobj->cursed ? "glow" :
  391.                   (is_shield(otmp) ? "layer" : "shield"));
  392.             }
  393.             if (otmp->oerodeproof && otmp->oeroded) {
  394.                 otmp->oeroded = 0;
  395.                 Your("%s %ss good as new!",
  396.                  xname(otmp), Blind ? "feel" : "look");
  397.             }
  398.             break;
  399.         }
  400.         if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
  401.                 && rn2(otmp->spe) && !sobj->cursed) {
  402.         Your("%s violently %s%s for a while, then evaporates.",
  403.                 xname(otmp),
  404.                 Blind ? "vibrates" : "glows ",
  405.                 Blind ? nul : Hallucination ? hcolor() : silver);
  406.             if(is_cloak(otmp)) (void) Cloak_off();
  407.             if(is_boots(otmp)) (void) Boots_off();
  408.             if(is_helmet(otmp)) (void) Helmet_off();
  409.             if(is_gloves(otmp)) (void) Gloves_off();
  410.             if(is_shield(otmp)) (void) Shield_off();
  411.             if(otmp == uarm) (void) Armor_gone();
  412.             useup(otmp);
  413.             break;
  414.         }
  415.         s = sobj->cursed ? -1 :
  416.             otmp->spe >= 9 ? (rn2(otmp->spe) == 0) :
  417.             sobj->blessed ? rnd(3-otmp->spe/3) : 1;
  418.         if (s >= 0 && otmp->otyp >= GRAY_DRAGON_SCALES &&
  419.                     otmp->otyp <= YELLOW_DRAGON_SCALES) {
  420.             /* dragon scales get turned into dragon scale mail */
  421.             Your("%s merges and hardens!", xname(otmp));
  422.             setworn((struct obj *)0, W_ARM);
  423.             /* assumes same order */
  424.             otmp->otyp = GRAY_DRAGON_SCALE_MAIL +
  425.                         otmp->otyp - GRAY_DRAGON_SCALES;
  426.             otmp->cursed = 0;
  427.             if (sobj->blessed) {
  428.                 otmp->spe++;
  429.                 otmp->blessed = 1;
  430.             }
  431.             otmp->known = 1;
  432.             setworn(otmp, W_ARM);
  433.             break;
  434.         }
  435.         Your("%s %s%s%s for a %s.",
  436.             xname(otmp),
  437.                 s == 0 ? "violently " : nul,
  438.             Blind ? "vibrates" : "glows ",
  439.             Blind ? nul : Hallucination ? hcolor() :
  440.               sobj->cursed ? Black : silver,
  441.               (s*s>1) ? "while" : "moment");
  442.         otmp->cursed = sobj->cursed;
  443.         if (!otmp->blessed || sobj->cursed)
  444.             otmp->blessed = sobj->blessed;
  445.         if (s) {
  446.             otmp->spe += s;
  447.             adj_abon(otmp, s);
  448.         }
  449.  
  450.         /* an elven magic clue, cookie@keebler */
  451.         if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
  452.                 && (is_elven_armor(otmp) || !rn2(7)))
  453.             Your("%s suddenly vibrates %s.",
  454.                 xname(otmp),
  455.                 Blind ? "again" : "unexpectedly");
  456.         break;
  457.         }
  458.     case SCR_DESTROY_ARMOR:
  459.         {
  460.         otmp = some_armor();
  461.         if(confused) {
  462.             if(!otmp) {
  463.                 strange_feeling(sobj,"Your bones itch.");
  464.                 exercise(A_STR, FALSE);
  465.                 exercise(A_CON, FALSE);
  466.                 return(1);
  467.             }
  468.             otmp->oerodeproof = sobj->cursed;
  469.             p_glow2(otmp,purple);
  470.             break;
  471.         }
  472.         if(!sobj->cursed || !otmp || !otmp->cursed) {
  473.             if(!destroy_arm(otmp)) {
  474.             strange_feeling(sobj,"Your skin itches.");
  475.             exercise(A_STR, FALSE);
  476.             exercise(A_CON, FALSE);
  477.             return(1);
  478.             }
  479.         } else {    /* armor and scroll both cursed */
  480.             Your("%s vibrates.", xname(otmp));
  481.             if (otmp->spe >= -6) otmp->spe--;
  482.             make_stunned(HStun + rn1(10, 10), TRUE);
  483.         }
  484.         }
  485.         break;
  486.     case SCR_CONFUSE_MONSTER:
  487.     case SPE_CONFUSE_MONSTER:
  488.         if(u.usym != S_HUMAN || sobj->cursed) {
  489.             if(!HConfusion) You("feel confused.");
  490.             make_confused(HConfusion + rnd(100),FALSE);
  491.         } else  if(confused) {
  492.             if(!sobj->blessed) {
  493.             Your("%s begin to %s%s.",
  494.                 makeplural(body_part(HAND)),
  495.                 Blind ? "tingle" : "glow ",
  496.                 Blind ? nul : Hallucination ? hcolor() : purple);
  497.             make_confused(HConfusion + rnd(100),FALSE);
  498.             } else {
  499.             pline("A %s%s surrounds your %s.",
  500.                 Blind ? nul : Hallucination ? hcolor() : red,
  501.                 Blind ? "faint buzz" : " glow",
  502.                 body_part(HEAD));
  503.             make_confused(0L,TRUE);
  504.             }
  505.         } else {
  506.             if (!sobj->blessed) {
  507.             Your("%s%s %s%s.",
  508.             makeplural(body_part(HAND)),
  509.             Blind ? "" : " begin to glow",
  510.             Blind ? (const char *)"tingle" : Hallucination ? hcolor() : red,
  511.             u.umconf ? " even more" : "");
  512.             u.umconf++;
  513.             } else {
  514.             if (Blind)
  515.                 Your("%s tingle %s sharply.",
  516.                 makeplural(body_part(HAND)),
  517.                 u.umconf ? "even more" : "very");
  518.             else
  519.                 Your("%s glow a%s brilliant %s.",
  520.                 makeplural(body_part(HAND)),
  521.                 u.umconf ? "n even more" : "",
  522.                 Hallucination ? hcolor() : red);
  523.             u.umconf += rn1(8, 2);
  524.             }
  525.         }
  526.         break;
  527.     case SCR_SCARE_MONSTER:
  528.     case SPE_CAUSE_FEAR:
  529.         {    register int ct = 0;
  530.         register struct monst *mtmp;
  531.  
  532.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  533.             if(cansee(mtmp->mx,mtmp->my)) {
  534.             if(confused || sobj->cursed) {
  535.                 mtmp->mflee = mtmp->mfrozen = mtmp->msleep = 0;
  536.                 mtmp->mcanmove = 1;
  537.             } else
  538.                 if (! resist(mtmp, sobj->oclass, 0, NOTELL))
  539.                 mtmp->mflee = 1;
  540.             if(!mtmp->mtame) ct++;    /* pets don't laugh at you */
  541.             }
  542.         if(!ct)
  543.               You("hear %s in the distance.",
  544.                    (confused || sobj->cursed) ? "sad wailing" :
  545.                             "maniacal laughter");
  546.         else if(sobj->otyp == SCR_SCARE_MONSTER)
  547.             You("hear %s close by.",
  548.                   (confused || sobj->cursed) ? "sad wailing" :
  549.                          "maniacal laughter");
  550.         break;
  551.         }
  552.     case SCR_BLANK_PAPER:
  553.         if (Blind)
  554.         You("don't remember there being any magic words on this scroll.");
  555.         else
  556.         pline("This scroll seems to be blank.");
  557.         known = TRUE;
  558.         break;
  559.     case SCR_REMOVE_CURSE:
  560.     case SPE_REMOVE_CURSE:
  561.         {    register struct obj *obj;
  562.         if(confused)
  563.             if (Hallucination)
  564.             You("feel the power of the Force against you!");
  565.             else
  566.             You("feel like you need some help.");
  567.         else
  568.             if (Hallucination)
  569.             You("feel in touch with the Universal Oneness.");
  570.             else
  571.             You("feel like someone is helping you.");
  572.  
  573.         if(sobj->cursed) pline("The scroll disintegrates.");
  574.         else {
  575.             for(obj = invent; obj ; obj = obj->nobj)
  576.             if(sobj->blessed || obj->owornmask ||
  577.                (obj->otyp == LOADSTONE)) {
  578.                 if(confused) blessorcurse(obj, 2);
  579.                 else uncurse(obj);
  580.             }
  581.         }
  582.         if(Punished && !confused) unpunish();
  583.         break;
  584.         }
  585.     case SCR_CREATE_MONSTER:
  586. #if defined(WIZARD) || defined(EXPLORE_MODE)
  587.         if (wizard || discover)
  588.         known = TRUE;
  589. #endif /* WIZARD || EXPLORE_MODE */
  590.     case SPE_CREATE_MONSTER:
  591.         {    register int cnt = 1;
  592.  
  593.         if(!rn2(73) && !sobj->blessed) cnt += rnd(4);
  594.         if(confused || sobj->cursed) cnt += 12;
  595.         while(cnt--) {
  596. #if defined(WIZARD) || defined(EXPLORE_MODE)
  597.             if((!wizard && !discover) || !create_particular())
  598. #endif /* WIZARD || EXPLORE_MODE */
  599.             (void) makemon (confused ? &mons[PM_ACID_BLOB] :
  600.                     (struct permonst *) 0, u.ux, u.uy);
  601.         }
  602.         break;
  603.         }
  604. /*        break;    /*NOTREACHED*/
  605.     case SCR_ENCHANT_WEAPON:
  606.         if(uwep && (uwep->oclass == WEAPON_CLASS ||
  607.                 uwep->otyp == PICK_AXE ||
  608.                 uwep->otyp == UNICORN_HORN) && confused) {
  609.         /* oclass check added 10/25/86 GAN */
  610.             uwep->oerodeproof = !(sobj->cursed);
  611.             if(Blind) {
  612.                 uwep->rknown = FALSE;
  613.                 Your("weapon feels warm for a moment.");
  614.             } else {
  615.                 uwep->rknown = TRUE;
  616.                 Your("%s covered by a %s %s %s!",
  617.                 aobjnam(uwep, "are"),
  618.                 sobj->cursed ? "mottled" : "shimmering",
  619.                 Hallucination ? hcolor() :
  620.                   sobj->cursed ? purple : golden,
  621.                 sobj->cursed ? "glow" : "shield");
  622.             }
  623.             if (uwep->oerodeproof && uwep->oeroded) {
  624.                 uwep->oeroded = 0;
  625.                 Your("%s good as new!",
  626.                  aobjnam(uwep, Blind ? "feel" : "look"));
  627.             }
  628.         } else return !chwepon(sobj,
  629.                        sobj->cursed ? -1 :
  630.                        !uwep ? 1 :
  631.                        uwep->spe >= 9 ? (rn2(uwep->spe) == 0) :
  632.                        sobj->blessed ? rnd(3-uwep->spe/3) : 1);
  633.         break;
  634.     case SCR_TAMING:
  635.     case SPE_CHARM_MONSTER:
  636.         {    register int i,j;
  637.         register int bd = confused ? 5 : 1;
  638.         register struct monst *mtmp;
  639.  
  640.         for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
  641.         if(isok(u.ux+i, u.uy+j) && (mtmp = m_at(u.ux+i, u.uy+j))) {
  642.             if(sobj->cursed) {
  643.             if(!mtmp->mtame) mtmp->mpeaceful = 0;
  644.             } else {
  645.             if (mtmp->isshk) {
  646.                 if (!mtmp->mpeaceful) {
  647.                 pline("%s calms down.", Monnam(mtmp));
  648.                 mtmp->mpeaceful = 1;
  649.                 }
  650.             } else if(!resist(mtmp, sobj->oclass, 0, NOTELL))
  651.                 (void) tamedog(mtmp, (struct obj *) 0);
  652.             }
  653.         }
  654.         break;
  655.         }
  656.     case SCR_GENOCIDE:
  657.         You("have found a scroll of genocide!");
  658.         known = TRUE;
  659.         if (sobj->blessed) do_class_genocide();
  660.         else do_genocide(!sobj->cursed | (2 * !!Confusion));
  661.         break;
  662.     case SCR_LIGHT:
  663.         if(!Blind) known = TRUE;
  664.         litroom(!confused && !sobj->cursed, sobj);
  665.         break;
  666.     case SCR_TELEPORTATION:
  667.         if(confused || sobj->cursed) level_tele();
  668.         else {
  669.             if (sobj->blessed && !Teleport_control) {
  670.                 known = TRUE;
  671.                 if (yn("Do you wish to teleport?")=='n')
  672.                     break;
  673.             }
  674.             tele();
  675.             if(Teleport_control || !couldsee(u.ux0, u.uy0) ||
  676.                (distu(u.ux0, u.uy0) >= 16))
  677.                 known = TRUE;
  678.         }
  679.         break;
  680.     case SCR_GOLD_DETECTION:
  681.         if (confused || sobj->cursed) return(trap_detect(sobj));
  682.         else return(gold_detect(sobj));
  683.     case SCR_FOOD_DETECTION:
  684.     case SPE_DETECT_FOOD:
  685.         if (food_detect(sobj))
  686.             return(1);    /* nothing detected */
  687.         break;
  688.     case SPE_IDENTIFY:
  689.         cval = rn2(5);
  690.         goto id;
  691.     case SCR_IDENTIFY:
  692.         /* known = TRUE; */
  693.         if(confused)
  694.             You("identify this as an identify scroll.");
  695.         else
  696.             pline("This is an identify scroll.");
  697.         if (sobj->blessed || (!sobj->cursed && !rn2(5)))
  698.             cval = rn2(5);
  699.             /* Note: if rn2(5)==0, identify all items */
  700.         else    cval = 1;
  701.         useup(sobj);
  702.         makeknown(SCR_IDENTIFY);
  703.     id:
  704.         if(invent && !confused) {
  705.             int ret;
  706.             do {
  707.             ret = ggetobj("identify", identify, cval);
  708.             } while(cval && (cval -= ret));
  709.         }
  710.         return(1);
  711.     case SCR_CHARGING:
  712.         if (confused) {
  713.             You("feel charged up!");
  714.             if (u.uen < u.uenmax)
  715.             u.uen = u.uenmax;
  716.             else
  717.             u.uen = (u.uenmax += d(5,4));
  718.             flags.botl = 1;
  719.             break;
  720.         }
  721.         known = TRUE;
  722.         pline("This is a charging scroll.");
  723.         otmp = getobj(all_count, "charge");
  724.         if (!otmp) break;
  725.         recharge(otmp, sobj->cursed ? -1 : (sobj->blessed ? 1 : 0));
  726.         break;
  727.     case SCR_MAGIC_MAPPING:
  728.         if (level.flags.nommap) {
  729.             Your("mind is filled with crazy lines!");
  730.             if (Hallucination)
  731.             pline("Wow!  Modern art.");
  732.             else
  733.             Your("head spins in bewilderment.");
  734.             make_confused(HConfusion + rnd(30), FALSE);
  735.             break;
  736.         }
  737.         known = TRUE;
  738.     case SPE_MAGIC_MAPPING:
  739.         if (level.flags.nommap) {
  740.             Your("head spins as something blocks the spell!");
  741.             make_confused(HConfusion + rnd(30), FALSE);
  742.             break;
  743.         }
  744.         pline("A map coalesces in your mind!");
  745.         cval = (sobj->cursed && !confused);
  746.         if(cval) HConfusion = 1;    /* to screw up map */
  747.         do_mapping();
  748.         if(cval) {
  749.             HConfusion = 0;        /* restore */
  750.             pline("Unfortunately, you can't grasp the details.");
  751.         }
  752.         break;
  753.     case SCR_AMNESIA:
  754.         known = TRUE;
  755.         forget( ((!sobj->blessed) << 1) | (!confused || sobj->cursed) );
  756.         if (Hallucination) /* Ommmmmm! */
  757.             Your("mind releases itself from mundane concerns.");
  758.         else if (!strncmpi(plname, "Maud", 4))
  759.             pline("As your mind turns inward on itself, you forget everything else.");
  760.         else if (rn2(2))
  761.             pline("Who was that Maud person anyway?");
  762.         else
  763.             pline("Thinking of Maud you forget everything else.");
  764.         exercise(A_WIS, FALSE);
  765.         break;
  766.     case SCR_FIRE:
  767.         /*
  768.          * Note: Modifications have been made as of 3.0 to allow for
  769.          * some damage under all potential cases.
  770.          */
  771.         cval = bcsign(sobj);
  772.         useup(sobj);
  773.         makeknown(SCR_FIRE);
  774.         if(confused) {
  775.             if(Fire_resistance) {
  776.               shieldeff(u.ux, u.uy);
  777.             if(!Blind)
  778.                 pline("Oh, look, what a pretty fire in your %s.",
  779.                 makeplural(body_part(HAND)));
  780.             else You("feel a pleasant warmth in your %s.",
  781.                 makeplural(body_part(HAND)));
  782.             } else {
  783.             pline("The scroll catches fire and you burn your %s.",
  784.                 makeplural(body_part(HAND)));
  785.             losehp(1, "scroll of fire", KILLED_BY_AN);
  786.             }
  787.             return(1);
  788.         }
  789.         if (Underwater)
  790.             pline("The water around you vaporizes violently!");
  791.         else
  792.             pline("The scroll erupts in a tower of flame!");
  793.         explode(u.ux, u.uy, 11, (2*(rn1(3, 3) + 2 * cval) + 1)/3,
  794.                             SCROLL_CLASS);
  795.         return(1);
  796.     case SCR_PUNISHMENT:
  797.         known = TRUE;
  798.         if(confused || sobj->blessed) {
  799.             You("feel guilty.");
  800.             break;
  801.         }
  802.         punish(sobj);
  803.         break;
  804.     default:
  805.         impossible("What weird effect is this? (%u)", sobj->otyp);
  806.     }
  807.     return(0);
  808. }
  809.  
  810. static void
  811. wand_explode(obj)
  812. register struct obj *obj;
  813. {
  814.     Your("%s vibrates violently, and explodes!",xname(obj));
  815.     nhbell();
  816.     losehp(rn2(2*(u.uhpmax+1)/3),"exploding wand", KILLED_BY_AN);
  817.     useup(obj);
  818.     exercise(A_STR, FALSE);
  819. }
  820.  
  821. /*
  822.  * Low-level lit-field update routine.
  823.  */
  824. STATIC_PTR void
  825. set_lit(x,y,val)
  826. int x, y;
  827. genericptr_t val;
  828. {
  829.     levl[x][y].lit = (val == (genericptr_t)-1) ? 0 : 1;
  830.     return;
  831. }
  832.  
  833. void
  834. litroom(on,obj)
  835. register boolean on;
  836. struct obj *obj;
  837. {
  838.     /* first produce the text (provided you're not blind) */
  839.     if(Blind) goto do_it;
  840.     if(!on) {
  841.         if(u.uswallow) {
  842.             pline("It seems even darker in here than before.");
  843.             return;
  844.         }
  845.         You("are surrounded by darkness!");
  846.     } else {
  847.         if(u.uswallow){
  848.             if (is_animal(u.ustuck->data))
  849.                 pline("%s stomach is lit.",
  850.                          s_suffix(Monnam(u.ustuck)));
  851.             else
  852.                 if (is_whirly(u.ustuck->data))
  853.                     pline("%s shines briefly.",
  854.                           Monnam(u.ustuck));
  855.                 else
  856.                     pline("%s glistens.", Monnam(u.ustuck));
  857.             return;
  858.         }
  859.         pline("A lit field surrounds you!");
  860.     }
  861.  
  862. do_it:
  863.     /* No-op in water - can only see the adjacent squares and that's it! */
  864.     if (Underwater || Is_waterlevel(&u.uz)) return;
  865.     /*
  866.      *  If we are darkening the room and the hero is punished but not
  867.      *  blind, then we have to pick up and replace the ball and chain so
  868.      *  that we don't remember them if they are out of sight.
  869.      */
  870.     if (Punished && !on && !Blind)
  871.         move_bc(1, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
  872.  
  873. #ifdef REINCARNATION
  874.     if (Is_rogue_level(&u.uz)) {
  875.         /* Can't use do_clear_area because MAX_RADIUS is too small */
  876.         /* rogue lighting must light the entire room */
  877.         int rnum = levl[u.ux][u.uy].roomno - ROOMOFFSET;
  878.         int rx, ry;
  879.         if(rnum >= 0) {
  880.         for(rx = rooms[rnum].lx-1; rx <= rooms[rnum].hx+1; rx++)
  881.             for(ry = rooms[rnum].ly-1; ry <= rooms[rnum].hy+1; ry++)
  882.             set_lit(rx, ry, (genericptr_t)((on)? 1 : -1));
  883.         rooms[rnum].rlit = on;
  884.         }
  885.         /* hallways remain dark on the rogue level */
  886.     } else
  887. #endif
  888.         do_clear_area(u.ux,u.uy,
  889.         (obj && obj->oclass==SCROLL_CLASS && obj->blessed) ? 9 : 5,
  890.         set_lit, (genericptr_t)((on)? 1 : -1));
  891.  
  892.     /*
  893.      *  If we are not blind, then force a redraw on all positions in sight
  894.      *  by temporarily blinding the hero.  The vision recalculation will
  895.      *  correctly update all previously seen positions *and* correctly
  896.      *  set the waslit bit [could be messed up from above].
  897.      */
  898.     if (!Blind) {
  899.         vision_recalc(2);
  900.  
  901.         /* replace ball&chain */
  902.         if (Punished && !on)
  903.         move_bc(0, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
  904.     }
  905.  
  906.     vision_full_recalc = 1;    /* delayed vision recalculation */
  907. }
  908.  
  909. static void
  910. do_class_genocide()
  911. {
  912.     register int i, j, immunecnt, gonecnt, goodcnt, class;
  913.     char buf[BUFSZ];
  914.  
  915.     for(j=0; ; j++) {
  916.         if (j >= 5) {
  917.             pline(thats_enough_tries);
  918.             return;
  919.         }
  920.         do {
  921.     getlin("What class of monsters do you wish to genocide? [type a letter]",
  922.        buf);
  923.         } while (buf[0]=='\033' || strlen(buf) != 1);
  924.         immunecnt = gonecnt = goodcnt = 0;
  925.         class = def_char_to_monclass(buf[0]);
  926.         for(i = 0; i < NUMMONS; i++) {
  927.             if(mons[i].mlet == class) {
  928.                 if (!(mons[i].geno & G_GENO)) immunecnt++;
  929.                 else if(mons[i].geno & G_GENOD) gonecnt++;
  930.                 else goodcnt++;
  931.             }
  932.         }
  933.         if (!goodcnt && class != S_HUMAN) {
  934.             if (gonecnt)
  935.     pline("All such monsters are already nonexistent.");
  936.             else if (immunecnt)
  937.     You("aren't permitted to genocide such monsters.");
  938.             else
  939.     pline("That symbol does not represent any monster.");
  940.             continue;
  941.         }
  942.         for(i = 0; i < NUMMONS; i++) {
  943.             if(mons[i].mlet == class) {
  944.             register struct monst *mtmp, *mtmp2;
  945.             char *n = makeplural(mons[i].mname);
  946.  
  947.             if (&mons[i]==player_mon() || ((mons[i].geno & G_GENO)
  948.                 && !(mons[i].geno & G_GENOD))) {
  949.             /* This check must be first since player monsters might
  950.              * have G_GENOD or !G_GENO.
  951.              */
  952.                 pline("Wiped out all %s.", n);
  953.                 if (&mons[i] == player_mon()) {
  954.                 u.uhp = -1;
  955.                 killer_format = KILLED_BY_AN;
  956.                 killer = "scroll of genocide";
  957. #ifdef POLYSELF
  958.                 if (u.umonnum >= 0)
  959.                     You("feel dead inside.");
  960.                 else
  961. #endif
  962.                     done(GENOCIDED);
  963.                 }
  964.                 /* for simplicity (and fairness) let's avoid
  965.                  * alignment changes here...
  966.                  */
  967. #ifdef POLYSELF
  968.                 if (i==u.umonnum) rehumanize();
  969. #endif
  970.                 mons[i].geno |= G_GENOD;
  971.                 for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  972.                 mtmp2 = mtmp->nmon;
  973.                 if(mtmp->data == &mons[i])
  974.                     mondead(mtmp);
  975.                 }
  976.             } else if (mons[i].geno & G_GENOD)
  977.                 pline("All %s are already nonexistent.", n);
  978.             else
  979.                 You("aren't permitted to genocide %s%s.",
  980.                 i == PM_WIZARD_OF_YENDOR ? "the " : "",
  981.                 type_is_pname(&mons[i]) ? mons[i].mname : (const char *)n);
  982.             }
  983.         }
  984.         return;
  985.     }
  986. }
  987.  
  988. #define REALLY 1
  989. #define PLAYER 2
  990. void
  991. do_genocide(how)
  992. int how;
  993. /* 0 = no genocide; create monsters (cursed scroll) */
  994. /* 1 = normal genocide */
  995. /* 3 = forced genocide of player */
  996. {
  997.     char buf[BUFSZ];
  998.     register int    i, j, killplayer = 0;
  999.     register struct permonst *ptr;
  1000.     register struct monst *mtmp, *mtmp2;
  1001.  
  1002.     if (how & PLAYER) {
  1003.         ptr = player_mon();
  1004.         Strcpy(buf, ptr->mname);
  1005.         killplayer++;
  1006.     } else {
  1007.         for(j = 0; ; j++) {
  1008.         if(j >= 5) {
  1009.             pline(thats_enough_tries);
  1010.             return;
  1011.         }
  1012.         getlin("What monster do you want to genocide? [type the name]",
  1013.             buf);
  1014.  
  1015.         i = name_to_mon(buf);
  1016.         if(i == -1 || (mons[i].geno & G_GENOD)) {
  1017.             pline("Such creatures do not exist in this world.");
  1018.             continue;
  1019.         }
  1020.         ptr = &mons[i];
  1021.         if (ptr == player_mon()) {
  1022.             killplayer++;
  1023.             goto deadmeat;
  1024.         }
  1025.         if (is_human(ptr)) adjalign(-sgn(u.ualign.type));
  1026.         if (is_demon(ptr)) adjalign(sgn(u.ualign.type));
  1027.  
  1028.         if(!(ptr->geno & G_GENO))  {
  1029.             if(flags.soundok) {
  1030.                 if(flags.verbose)
  1031.             pline("A thunderous voice booms though the caverns:");
  1032.                 pline("\"No, mortal!  That will not be done.\"");
  1033.             }
  1034.             continue;
  1035.         }
  1036.         break;
  1037.         }
  1038.     }
  1039. deadmeat:
  1040.     if (Hallucination) {
  1041. #ifdef POLYSELF
  1042.         if (u.umonnum != -1)
  1043.         Strcpy(buf,uasmon->mname);
  1044.         else
  1045. #endif
  1046.         {
  1047.         Strcpy(buf, pl_character);
  1048.         buf[0] += 'a' - 'A';
  1049.         }
  1050.     } else Strcpy(buf,ptr->mname); /* make sure we have standard singular */
  1051.     if (how & REALLY) {
  1052.         pline("Wiped out all %s.", makeplural(buf));
  1053.         if(killplayer) {
  1054.         u.uhp = -1;
  1055.         killer_format = KILLED_BY_AN;
  1056.         killer = "genocide spell";
  1057. #ifdef POLYSELF
  1058.     /* Polymorphed characters will die as soon as they're rehumanized. */
  1059.         if(u.umonnum >= 0)    You("feel dead inside.");
  1060.         else
  1061. #endif
  1062.             done(GENOCIDED);
  1063.         return;
  1064.         }
  1065. #ifdef POLYSELF
  1066.         else if (ptr == uasmon) rehumanize();
  1067. #endif
  1068.         ptr->geno |= G_GENOD;
  1069.         for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  1070.         mtmp2 = mtmp->nmon;
  1071.         if(mtmp->data == ptr)
  1072.             mondead(mtmp);
  1073.         }
  1074.     } else if (!(ptr->geno & G_EXTINCT)) {
  1075.         pline("Sent in some %s.", makeplural(buf));
  1076.         j = rn1(3, 4);
  1077.         for(i=1; i<=j; i++) {
  1078.         struct monst *mmon = makemon(ptr, u.ux, u.uy);
  1079.         struct obj *otmp;
  1080.  
  1081.         while ((otmp = mmon->minvent) != 0) {
  1082.             mmon->minvent = otmp->nobj;
  1083.             dealloc_obj(otmp);
  1084.         }
  1085.         }
  1086.     }
  1087. }
  1088.  
  1089. #endif /* OVLB */
  1090. #ifdef OVLB
  1091.  
  1092. void
  1093. punish(sobj)
  1094. register struct obj    *sobj;
  1095. {
  1096.     You("are being punished for your misbehavior!");
  1097.     if(Punished){
  1098.         Your("iron ball gets heavier.");
  1099.         uball->owt += 160 * (1 + sobj->cursed);
  1100.         return;
  1101.     }
  1102.     setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN);
  1103.     setworn(mkobj(BALL_CLASS, TRUE), W_BALL);
  1104.     uball->spe = 1;        /* special ball (see save) */
  1105.  
  1106.     /*
  1107.      *  Place ball & chain if not swallowed.  If swallowed, the ball &
  1108.      *  chain variables will be set at the next call to placebc().
  1109.      */
  1110.     if (!u.uswallow) {
  1111.         placebc();
  1112.         if (Blind) set_bc(1);    /* set up ball and chain variables */
  1113.         newsym(u.ux,u.uy);        /* see ball&chain if can't see self */
  1114.     }
  1115. }
  1116.  
  1117. void
  1118. unpunish()
  1119. {        /* remove the ball and chain */
  1120.     freeobj(uchain);
  1121.     newsym(uchain->ox,uchain->oy);
  1122.     dealloc_obj(uchain);
  1123.     setworn((struct obj *)0, W_CHAIN);
  1124.     uball->spe = 0;
  1125.     setworn((struct obj *)0, W_BALL);
  1126. }
  1127.  
  1128. /* some creatures have special data structures that only make sense in their
  1129.  * normal locations -- if the player tries to create one elsewhere, or to revive
  1130.  * one, the disoriented creature becomes a zombie
  1131.  */
  1132. boolean
  1133. cant_create(mtype)
  1134. int *mtype;
  1135. {
  1136.  
  1137.     if (*mtype==PM_GUARD || *mtype==PM_SHOPKEEPER
  1138.          || *mtype==PM_ALIGNED_PRIEST || *mtype==PM_ANGEL) {
  1139.         *mtype = PM_HUMAN_ZOMBIE;
  1140.         return TRUE;
  1141.     }
  1142.     return FALSE;
  1143. }
  1144.  
  1145. #if defined(WIZARD) || defined(EXPLORE_MODE)
  1146. boolean
  1147. create_particular()
  1148. {
  1149.     char buf[BUFSZ];
  1150.     int which, tries = 0;
  1151.  
  1152.     do {
  1153.         getlin("Create what kind of monster? [type the name]", buf);
  1154.         which = name_to_mon(buf);
  1155.         if (which < 0) pline("I've never heard of such monsters.");
  1156.         else break;
  1157.     } while (++tries < 5);
  1158.     if (tries == 5) pline(thats_enough_tries);
  1159.     else {
  1160.         if (!(mons[which].geno & G_GENOD) && cant_create(&which) &&
  1161.                                 !Blind) {
  1162.         if (mons[which].geno & G_GENOD)
  1163. pline("An image of the creature forms, wavers momentarily, then fades.");
  1164.         else
  1165. pline("The disoriented creature's eyes slowly glaze over.");
  1166.         }
  1167.         (void) makemon(&mons[which], u.ux, u.uy);
  1168.         return TRUE;
  1169.     }
  1170.     return FALSE;
  1171. }
  1172. #endif /* WIZARD || EXPLORE_MODE */
  1173.  
  1174. #endif /* OVLB */
  1175.  
  1176. /*read.c*/
  1177.